人格套件 - SAORI

套件使用

人格套件(SAORI)是專門為了擴充人格機能而製作的一種外掛插件(plugin),以實作諸如音樂播放、螢幕特效、字串處理、系統資訊等等偽AI所沒有提供的功能。基本上如果能善用這些套件的話,可以做出一般人格所做不到的事。

由於標準化的緣故,現今大多數的偽AI都支援在人格內呼叫人格套件的功能。如果你覺得一般的事件寫作已經無法滿足你的創作欲望的話,歡迎你加入這個大坑~。 (XD)

套件列表

相關頁面

外部連結

在Ghost中呼叫人格套件

不同的偽AI呼叫套件的方式都不一樣,但基本上大同小異。主要需要下列資訊:

  • 偽AI呼叫套件的函式名稱
  • 套件所在路徑
  • 套件的事件指令
  • 引數1、引數2、引數3、……

首先,你必須知道套件的規格與事件種類,這些通常都寫在隨套件附帶的 readme 文件,在使用前務必讀熟其內容。接下來,我們決定好要使用的事件指令後,就要根據事件的需求來輸入引數(argument)。

以播放音樂套件 mciaudior.dll 為例,它本身內建了 "load" 、 "play" 、 "loop" 、 "stop" 四種事件指令,其功能分別為 "載入音樂" 、 "播放" 、 "重複播放" 、 "停止" 。其中 "load" 這個指令需要使用者提供音樂的路徑,其餘三者則不需要任何額外的引數。於是當我們要透過 mciaudior.dll 來播放音樂的時候,我們要這麼寫:

  • 美坂的呼叫方式
    {$saori("mciaudior.dll","load","C:\music\op.mp3")}
    {$saori("mciaudior.dll","play")}
  • 文的呼叫方式
    FUNCTIONEX("mciaudior.dll","load","C:\music\op.mp3");
    FUNCTIONEX("mciaudior.dll","play");
  • 華和梨的呼叫方式
    $(callsaori mciaudio.dll load C:\music\op.mp3)
    $(callsaori mciaudio.dll play)

第一行指令先載入音樂的路徑,然後第二行則執行播放音樂的工作。這裡的路徑可以是相對路徑或絕對路徑,相對路徑會以人格 ghost\master 所在的資料夾為基準。

套件實作

人格套件分為 universal 與 BASIC 兩種型式, universal其實就是標準的DLL文件,而 BASIC 則是 Win32 Console Application ,也就是一般初學者在學C語言時最常使用的那種DOS風格的EXE程式,經由 proxy.dll 這個人格套件的傳換後,會把印出來的文字傳送到人格裡面。

基本範例

  • Universal
    請參考下面實例。
  • BASIC
    void main(int argc, char* argv[])
    {
      printf("Hello, world.");
    }

製作教學

首先請到csaori - Google Code下載CSaori的原始碼,這是日本方面預先寫好的Saori原型,裡面已經幫你做好除了你要寫的功能以外的所有事情。

下載好後,請開啟任意的C++ IDE開發工具(如Visual C++),建立一個空專案,將這兩個檔案加入專案之中。接下來,再新增一個cpp檔,並實作以下三個函式:

void CSAORI::exec(const CSAORIInput& in,CSAORIOutput& out)
bool CSAORI::load()
bool CSAORI::unload()

load()與unload()主要是處理記憶體配置的工作,如果你沒有做這些事情的需求,那麼直接回傳true即可。exec()就是實際實作功能的地方了,你主要要記住的事情有二:

  • 偽春菜呼叫Saori時所傳入的引數都在in.args中。
  • 你的輸出要放在out.value中。

最後再將專案的組態型別改成動態函式庫(.dll)即可。

現在,讓我們來實作一個簡單的例子。首先,我們要製作一個talk.dll,它的功能是當偽春菜呼叫此Saori並傳入「talk」字眼時,便回傳「喵。」。在這例子中我們定義第一個引數是決定是誰講話,第二個引數是決定要講什麼。例如當使用者呼叫

FUNCTIONEX('talk.dll', 'kero', 'cattalk');

時,我們便要在value[0]中回傳「\1喵。」。

那麼,我們首先在專案中加入一個talk.cpp,並將以下程式碼加入其中:

#include "csaori.h"

void CSAORI::exec(const CSAORIInput& in,CSAORIOutput& out)
{
    string_t s = L"";
    if (in.args[0] == L"sakura")
        s += L"\\0";
    else if (in.args[0] == L"kero")
        s += L"\\1";
    else
        return;

    if (in.args[1] == L"cattalk")
        s += L"喵。";
    else if (in.args[1] == L"dogtalk")
        s += L"汪。";
    else
        return;

    out.values.push_back(s);
}

bool CSAORI::load()
{
    return true;
}

bool CSAORI::unload()
{
    return true;
}

注意因為我們使用寬字串來運作,所以所有的字串的雙引號前面得加上「L」來告知編譯器這是個寬字元字串。接下來我們首先判斷第一引數是sakura 或是kero,然後決定要加入\0或\1到字串裡,如果都不相同的話則直接return什麼都不輸出,第二引數也是相同的道理。

再來便是輸出了,由於CSaori在這裡使用C++的vector容器,因此要增加元素的話就要用push_back這個成員函數來新增。之後CSaori的內部函式會把你加到out.value中的字串做成核心程式看得懂的格式回傳給偽春菜。

(注意:如果你看不懂我這邊在寫什麼,那麼建議你去買本C++的書來看看會比較好。)

接下來就是編譯了,記得把你的專案組態換成.dll型式。編譯好後將產生出來的dll檔複製到ghost資料夾底下,就可以運作了。

一個簡單的AYA版呼叫例子:

FUNCTIONEX('talk.dll', 'kero', 'cattalk');
"%(valueex0)\n";

有沒有發現使魔叫了聲「喵。」呢?XD

加註

由於美坂在語系支援上的缺陷,此專案產生的SAORI在美坂下會顯示亂碼。

除了用Saori Value[n]多值返回格式之外,也可用Saori return result格式,做法是將

out.values.push_back(s);

改成

out.result = s;

此時的呼叫範例如下:

_ret = FUNCTIONEX('talk.dll', 'kero', 'cattalk');
"%(_ret)\n";

相關資料(日文)

SAORI - universal (DLL形式)

SAORI - basic (EXE形式)

討論區

如果想討論SAORI開發相關的問題,可以到這裡一起參與討論:

http://cuc.moe.hm/


首頁   編輯 封鎖 差異 備份 上傳檔案 複製 變更名稱 重新載入   新建條目 一覽 搜索 最近的變更   幫助   最近更新的RSS
Last-modified: 2012-09-13 (四) 22:31:16 (4058d)